﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using WorkFlowCore.Conditions;
using WorkFlowCore.EventHandlers;
using WorkFlowCore.IRepositories;
using WorkFlowCore.UserSelectors;
using WorkFlowCore.Workflows;
using WorkFlowCore.WorkTasks;

namespace WorkFlowCore
{
    public class WorkflowManager
    {
        private readonly IBasicRepository<Workflow, Guid> workflowRepository;
        private readonly IBasicRepository<WorkflowVersion, Guid> versionRepository;
        private readonly IBasicRepository<WorkTask, Guid> workTaskRepository;
        private readonly IBasicRepository<WorkStep, Guid> workStepRepository;
        private readonly ConditionManager conditionManager;
        private readonly UserSelectorManager userSelectorManager;
        private readonly EventManager eventManager;

        public WorkflowManager(IBasicRepository<Workflow, Guid> workflowRepository, IBasicRepository<WorkflowVersion, Guid> versionRepository, IBasicRepository<WorkTask, Guid> workTaskRepository, IBasicRepository<WorkStep, Guid> workStepRepository, ConditionManager conditionManager, UserSelectorManager userSelectorManager, EventManager eventManager)
        {
            this.workflowRepository = workflowRepository;
            this.versionRepository = versionRepository;
            this.workTaskRepository = workTaskRepository;
            this.workStepRepository = workStepRepository;
            this.conditionManager = conditionManager;
            this.userSelectorManager = userSelectorManager;
            this.eventManager = eventManager;
        }


        #region 流程的增删改查

        public async Task<Workflow> CreateWorkflow(string workflowNo, string name, string description)
        {
            var workflow = new Workflow(Guid.NewGuid(), workflowNo, name, description);
            workflow = await workflowRepository.InsertAsync(workflow);
            var workflowVersion = new WorkflowVersion(Guid.NewGuid(), workflow.Id, workflow.ActiveVersion, string.Empty, description);
            await versionRepository.InsertAsync(workflowVersion);
            return workflow;
        }
        /// <summary>
        /// 更新流程激活版本
        /// </summary>
        /// <param name="workflowId"></param>
        /// <param name="activeVersion"></param>
        public async Task UpdateWorkflowActiveVersion(Guid workflowId, int activeVersion)
        {
            var workflow = await workflowRepository.GetAsync(workflowId);
            workflow.UpdateActiveVersion(activeVersion);
            await workflowRepository.UpdateAsync(workflow);
        }
        /// <summary>
        /// 删除流程
        /// </summary>
        /// <param name="workflowid"></param>
        /// <returns></returns>
        public async Task<bool> DeleteWorkflow(Guid workflowid)
        {
            //有被流程引用则不允许删除
            if (await workTaskRepository.GetCountAsync(wt => wt.WorkflowId.Id == workflowid) > 0) return false;
            await workflowRepository.DeleteManyAsync(wt => wt.Id == workflowid);
            return true;
        }
        /// <summary>
        /// 删除流程版本
        /// </summary>
        /// <param name="workflowid"></param>
        /// <param name="versionId"></param>
        /// <returns></returns>
        public async Task<bool> DeleteWorkflowVersion(Guid workflowid, int versionId)
        {
            //有被流程引用则不允许删除
            if (await workTaskRepository.GetCountAsync(wt => wt.WorkflowId.Id == workflowid && wt.WorkflowId.VersionId == versionId) > 0) return false;
            await versionRepository.DeleteManyAsync(wt => wt.WorkflowId == workflowid && wt.VersionNo == versionId);
            return true;
        }

        private List<NodeMap> GetNewNodeMaps(List<WorkflowLine> workflowLines, List<WorkflowNode> workflowNodes)
        {
            var result = new List<NodeMap>();
            workflowLines.ForEach(line =>
            {
                var fromNode = workflowNodes.FirstOrDefault(n => n.Id == line.FromNodeId);
                var toNode = workflowNodes.FirstOrDefault(n => n.Id == line.ToNodeId);

                result.Add(NodeMap.Factory.NewNormalNodeMap(fromNode, toNode, line.Conditions));

                //如果指定拒绝节点，则按照拒绝节点配置拒绝映射，否则原路拒绝
                if (toNode.RejectNodes != null && toNode.RejectNodes.Count > 0)
                {
                    toNode.RejectNodes.ForEach(rn =>
                    {
                        var rejectFromNode = toNode;
                        var rejectToNode = workflowNodes.FirstOrDefault(n => n.Id == rn.NodeId);

                        result.Add(NodeMap.Factory.NewRejectNodeMap(rejectFromNode, rejectToNode, rn.Conditions));
                    });
                }
                else
                {
                    //判断起始节点是否是开始或会签节点，是的话，直接退回，不是的话，获取来所有以起始节点为终点的所有节点条件放入拒绝判断列表中
                    if (fromNode.NodeType == WorkNodeType.Begin || fromNode.NodeType == WorkNodeType.Sign || fromNode.NodeType == WorkNodeType.Judge || fromNode.NodeType == WorkNodeType.HandOut)
                    {
                        result.Add(NodeMap.Factory.NewRejectNodeMap(toNode, fromNode, null));
                    }
                    else
                    {
                        var fromLines = workflowLines.Where(line => line.ToNodeId == fromNode.Id).ToList();
                        fromLines.ForEach(line =>
                        {
                            result.Add(NodeMap.Factory.NewRejectNodeMap(toNode, fromNode, line.Conditions));
                        });
                    }
                }
            });
            return result;
        }

        public async Task<Workflow> UpdateWorkflow(Guid workflowId, string name, string description, int versionNo, string drawingInfo, string versionDescription, List<WorkflowLine> workflowLines, List<WorkflowNode> workflowNodes)
        {
            var workflow = await workflowRepository.GetAsync(workflowId);
            workflow.Update(name, description);
            await workflowRepository.UpdateAsync(workflow);

            var version = await versionRepository.GetAsync(v => v.WorkflowId == workflowId && v.VersionNo == versionNo);
            if (version == null)
            {
                //新建版本
                version = new WorkflowVersion(Guid.NewGuid(), workflowId, versionNo, drawingInfo, versionDescription);
                version.SetNodeMaps(GetNewNodeMaps(workflowLines, workflowNodes));
                await versionRepository.InsertAsync(version);
            }
            else
            {
                version.SetNodeMaps(GetNewNodeMaps(workflowLines, workflowNodes));
                version.Update(versionNo, drawingInfo, versionDescription);
                await versionRepository.UpdateAsync(version);
            }
            return workflow;
        }

        #endregion

        #region 流程审批操作

        private async Task<List<WorkflowNode>> GetAllNodesByWorkflowId(WorkflowId workflowId)
        {
            var workflowVersion = await versionRepository.GetAsync(v => v.WorkflowId == workflowId.Id && v.VersionNo == workflowId.VersionId);
            return workflowVersion.AllNodes;
        }
        private async Task<List<NodeMap>> GetAllNodeMapsByWorkflowId(WorkflowId workflowId)
        {
            var workflowVersion = await versionRepository.GetAsync(v => v.WorkflowId == workflowId.Id && v.VersionNo == workflowId.VersionId);
            return workflowVersion.NodeMaps;
        }

        private async Task<WorkflowNode> GetNodeByWorkflowIdAndNodeId(WorkflowId workflowId, Guid nodeId)
        {
            var workflowVersion = await versionRepository.GetAsync(v => v.WorkflowId == workflowId.Id && v.VersionNo == workflowId.VersionId);
            return workflowVersion.AllNodes.FirstOrDefault(n => n.Id == nodeId);
        }


        /// <summary>
        /// 获取审批的下一步节点
        /// </summary>
        /// <param name="node"></param>
        /// <param name="workTask"></param>
        /// <returns></returns>
        public async Task<List<WorkflowNode>> GetNextNodes(WorkflowNode node, WorkTask workTask, WorkStep cuttentWorkStep)
        {
            var nodes = new List<WorkflowNode>();

            var workflowVersion = await versionRepository.GetAsync(v => v.WorkflowId == workTask.WorkflowId.Id && v.VersionNo == workTask.WorkflowId.VersionId);

            var toNodeLines = workflowVersion.NodeMaps.Where(n => n.FromNode.Id == node.Id && n.MapType == NodeMap.NodeMapType.Normal);

            foreach (var line in toNodeLines)
            {
                if (line.CanAccept(workTask, cuttentWorkStep, conditionManager))
                {
                    var tonode = line.ToNode;
                    nodes.Add(tonode);
                }
            }
            return nodes;
        }
        /// <summary>
        /// 获取驳回的节点
        /// 根据当前步骤的前一个分组id获取同组的 所有nodeid
        /// </summary>
        /// <param name="node"></param>
        /// <param name="workTask"></param>
        /// <param name="currentWorkStep"></param>
        /// <returns></returns>
        public async Task<List<WorkflowNode>> GetRejectNodes(WorkflowNode node, WorkTask workTask, WorkStep currentWorkStep)
        {
            var workflowVersion = await versionRepository.GetAsync(v => v.WorkflowId == workTask.WorkflowId.Id && v.VersionNo == workTask.WorkflowId.VersionId);

            //var nodes = new List<WorkflowNode>();
            //var toNodeLines = workflowVersion.NodeMaps.Where(n => n.FromNode.Id == node.Id && n.MapType == NodeMap.NodeMapType.Reject);

            //foreach (var line in toNodeLines)
            //{
            //    if (line.CanAccept(workTask, currentWorkStep, conditionManager))
            //    {
            //        var tonode = line.ToNode;
            //        nodes.Add(tonode);
            //    }
            //}

            var preSteps = await workStepRepository.GetListAsync(ws => ws.GroupId == currentWorkStep.PreStepGroupId);
            var preNodeIds = preSteps.Select(ps => ps.NodeId).Distinct();

            return workflowVersion.AllNodes.Where(n => preNodeIds.Contains(n.Id)).ToList();

        }

        public async Task<List<WorkStep>> GetRejectSteps(WorkflowNode node, WorkTask workTask, WorkStep currentWorkStep)
        {
            /*
             * 如果指定了拒绝返回的节点，则按指定节点返回
             * 如果没指定返回节点，则判断来源节点是不是拒绝步骤，
             *  是   根据流程节点关系推断退回节点
             *  否   根据审批记录退回到上一个节点
             */

            var workflowVersion = await versionRepository.GetAsync(v => v.WorkflowId == workTask.WorkflowId.Id && v.VersionNo == workTask.WorkflowId.VersionId);
            var preSteps = await workStepRepository.GetListAsync(ws => ws.GroupId == currentWorkStep.PreStepGroupId);



            var groupId = Guid.NewGuid().ToString();
            var steps = new List<WorkStep>();
            if (node.RejectNodes != null && node.RejectNodes.Count > 0)
            {
                //如果指定了回滚的节点，则按指定节点回滚
                foreach (var rejectNode in node.RejectNodes)
                {
                    var toNode = workflowVersion.AllNodes.FirstOrDefault(n => n.Id == rejectNode.NodeId);
                    steps.AddRange(GetApproveSteps(currentWorkStep.NodeId, node.Name, workTask, toNode, currentWorkStep.GroupId, groupId));
                }
            }
            else if (preSteps.Count(ps=>ps.HandleType== WorkStepHandleType.Reject)>0)
            {
                var toNodeLines = workflowVersion.NodeMaps.Where(n => n.FromNode.Id == node.Id && n.MapType == NodeMap.NodeMapType.Reject);

                foreach (var line in toNodeLines)
                {
                    if (line.CanAccept(workTask, currentWorkStep, conditionManager))
                    {
                        var tonode = line.ToNode;
                        steps.AddRange(GetApproveSteps(currentWorkStep.NodeId, node.Name, workTask, tonode, currentWorkStep.GroupId, groupId));
                    }
                }
            }
            else
            {

                preSteps.ForEach(st =>
                {
                    steps.Add(st.Copy(groupId));
                });
            }



            return steps;
        }


        /// <summary>
        /// 获取节点派发的成员
        /// </summary>
        /// <param name="node"></param>
        /// <param name="workTask"></param>
        /// <returns></returns>
        public Dictionary<NodeUser.NodeHandleType, List<User>> GetNodeUsers(WorkflowNode node, WorkTask workTask)
        {
            return node.GetHandleUsers(workTask, userSelectorManager);
        }

        /// <summary>
        /// 获取节点的所有前节点
        /// </summary>
        /// <param name="node"></param>
        /// <returns></returns>
        public List<WorkflowNode> GetAllPreNodes(WorkflowNode node, List<NodeMap> nodeMaps)
        {
            var nodes = new List<WorkflowNode>();
            var preNodes = nodeMaps.Where(n => n.MapType == NodeMap.NodeMapType.Normal && n.ToNode.Id == node.Id).Select(n => n.FromNode);

            foreach (var item in preNodes)
            {
                nodes.Add(item);

                nodes.AddRange(GetAllPreNodes(item, nodeMaps));
            }
            return nodes;
        }

        /// <summary>
        /// 更新步骤状态为未处理
        /// </summary>
        /// <param name="currentNodeId"></param>
        /// <param name="stepGroupId"></param>
        /// <returns></returns>
        private async Task UpdateStepsStatusWithUnworkflowed(Guid currentNodeId, string stepGroupId)
        {
            await Task.Delay(0);

            //更新步骤所包含的节点状态为 未处理状态
            var steps = await workStepRepository.GetListAsync(s => s.NodeId != currentNodeId && s.GroupId == stepGroupId);
            foreach (var step in steps)
            {
                //对于未处理的记录，更新其处理状态
                if (!step.IsHandled)
                {
                    step.Handle(WorkStepHandleType.Unworkflowed);
                }
            }

        }
        /// <summary>
        /// 更新步骤状态为未处理
        /// 更新当前步骤所在节点的其它结点为  未处理 状态
        /// </summary>
        /// <param name="workTask"></param>
        /// <param name="currentWorkStep"></param>
        /// <returns></returns>
        private async Task UpdateStepsStatusWithUnworkflowed(WorkTask workTask, WorkStep currentWorkStep)
        {
            await Task.Delay(0);
            var steps = await workStepRepository.GetListAsync(ws => ws.NodeId == currentWorkStep.NodeId && ws.GroupId == currentWorkStep.GroupId && ws.Id != currentWorkStep.Id && !ws.IsHandled);
            foreach (var step in steps)
            {
                //对于未处理的记录，更新其处理状态
                if (!step.IsHandled)
                {
                    step.Handle(WorkStepHandleType.Unworkflowed);
                    await workStepRepository.UpdateAsync(step);
                }
            }

        }




        /// <summary>
        /// 发起审批
        /// </summary>
        /// <param name="node"></param>
        /// <returns></returns>
        public async Task<List<WorkStep>> WorkTaskStart(Guid workTaskId)
        {
            var workTask = await workTaskRepository.GetAsync(workTaskId);
            var workflowVersion = await versionRepository.GetAsync(v => v.WorkflowId == workTask.WorkflowId.Id && v.VersionNo == workTask.WorkflowId.VersionId);

            var startNode = workflowVersion.NodeMaps.FirstOrDefault(n => n.FromNode.NodeType == WorkNodeType.Begin)?.FromNode;

            var steps = GetApproveSteps(Guid.Empty, "", workTask, startNode, string.Empty, Guid.NewGuid().ToString());
            await SendTasks(workTask, steps, workTask.FormData);
            //更新流程状态为处理中
            var task = await workTaskRepository.GetAsync(workTask.Id);
            task.SetProcessing();
            await workTaskRepository.UpdateAsync(task);

            return steps;
        }

        /// <summary>
        /// 判断当前节点所有人员是否都处理完了
        /// </summary>
        /// <param name="currentWorkStep"></param>
        /// <param name="workTask"></param>
        /// <returns></returns>
        private async Task<bool> HasAllHandlersWorkflowed(WorkStep currentWorkStep, WorkTask workTask)
        {
            await Task.Delay(0);
            var GetCountAsync = await workStepRepository.GetCountAsync(ws => ws.GroupId == currentWorkStep.GroupId && ws.Id != currentWorkStep.Id && !ws.IsHandled);
            return GetCountAsync == 0;
        }

        /// <summary>
        /// 通过审批
        /// </summary>
        /// <param name="workStepId"></param>
        /// <param name="comment"></param>
        /// <param name="resourceIds"></param>
        /// <param name="UserSelectors"></param>
        /// <returns></returns>
        public async Task<ProveResult> PassApprove(Guid workStepId, string comment = null, string resourceIds = null, string formData = null, List<NodeUser> handlerUserSelectors = null, List<NodeUser> readUserSelectors = null)
        {
            var currentWorkStep = await workStepRepository.GetAsync(workStepId);
            if (currentWorkStep.IsHandled)
                return ProveResult.Failed("步骤已处理！");



            //派发下个节点任务
            var workTask = await workTaskRepository.GetAsync(currentWorkStep.WorkTaskId);
            var currentNode = await GetNodeByWorkflowIdAndNodeId(workTask.WorkflowId, currentWorkStep.NodeId);

            //更新当前处理节点为已处理
            currentWorkStep.Handle(WorkStepHandleType.Pass, comment, resourceIds);
            await workStepRepository.UpdateAsync(currentWorkStep);

            var steps = new List<WorkStep>();

            var nextNodes = await GetNextNodes(currentNode, workTask, currentWorkStep);

            if (currentNode.IsWaitingAllUser)
            {
                lock ("WorkNodeType.Sign")
                {
                    if (!HasAllHandlersWorkflowed(currentWorkStep, workTask).Result)
                    {
                        return ProveResult.Succeed(steps);
                    }
                }
            }
            else
            {
                await UpdateStepsStatusWithUnworkflowed(workTask, currentWorkStep);
            }
            //如果是会签操作,则确保所有会签中的操作都完成了才进行下一步
            if (nextNodes.Count == 1 && nextNodes[0].NodeType == WorkNodeType.Sign)
            {
                //会签
                //等待所有待处理的处理才继续
                lock ("WorkNodeType.Sign")
                {
                    if (GetOnHandingSignStepsCount(currentWorkStep.NodeId, currentWorkStep.GroupId).Result != 0)
                    {
                        return ProveResult.Succeed(steps); ;
                    }
                }
            }
            var nextGroupId = Guid.NewGuid().ToString();
            //如果是判断/分发操作,则递归调用审批自动往下
            //if (nextNodes.GetCountAsync == 1 && (nextNodes[0].NodeType == WorkNodeType.Judge))
            //{
            //    steps = GetApproveSteps(currentWorkStep.NodeId, currentNode.Name, workTask, nextNodes[0], currentWorkStep.GroupId, nextGroupId);
            //    workStepRepository.InsertAsync(steps[0]);
            //    return await PassApprove(steps[0].Id);
            //}

            foreach (var node in nextNodes)
            {
                //如果 指定了处理人，则直接派给处理人
                if (handlerUserSelectors != null && handlerUserSelectors.Count > 0)
                {
                    GetUsersByUserSelectors(handlerUserSelectors, null, user =>
                    {
                        steps.Add(new WorkStep(Guid.NewGuid(), workTask.Id, currentWorkStep.NodeId, currentNode.Name, node.Id, node.Name, new User
                        {
                            Id = user.Id,
                            Name = user.Name
                        }, WorkStepType.Handle, currentWorkStep.GroupId, nextGroupId));
                    });
                }
                else
                {
                    steps.AddRange(GetApproveSteps(currentWorkStep.NodeId, currentNode.Name, workTask, node, currentWorkStep.GroupId, nextGroupId));
                }
                //如果指定了 抄送（只读）人员，直接推送给抄送人员
                if (readUserSelectors != null && readUserSelectors.Count > 0)
                {
                    GetUsersByUserSelectors(readUserSelectors, null, user =>
                    {
                        steps.Add(new WorkStep(Guid.NewGuid(), workTask.Id, currentWorkStep.NodeId, currentNode.Name, node.Id, node.Name, new User
                        {
                            Id = user.Id,
                            Name = user.Name
                        }, WorkStepType.ReadOnly, currentWorkStep.GroupId, nextGroupId));
                    });
                }
            }



            //如果是结束流程,则发布结束事件
            if (currentNode.NodeType == WorkNodeType.End)
            {
                //更新流程状态为处理中
                var task = await workTaskRepository.GetAsync(workTask.Id);
                task.SetProcessed();
                await workTaskRepository.UpdateAsync(task);
                //TODO 发布流程结束事件
                eventManager.TriggerTaskFinished(task);
            }
            if (steps.Count == 0 && currentNode.NodeType != WorkNodeType.End)
                return ProveResult.Failed("找不到可以处理的下一个步骤！");
            await SendTasks(workTask, steps, formData);
            return ProveResult.Succeed(steps);
        }

        /// <summary>
        /// 驳回审批
        /// </summary>
        /// <param name="workTask"></param>
        /// <param name="currentNodeId"></param>
        /// <returns></returns>
        public async Task<ProveResult> RejectApprove(Guid workStepId, string comment = null, string resourceIds = null, string formData = null)
        {
            var currentWorkStep = await workStepRepository.GetAsync(workStepId);
            if (currentWorkStep.IsHandled)
                return ProveResult.Failed("步骤已处理！");


            var workTask = await workTaskRepository.GetAsync(currentWorkStep.WorkTaskId);

            //将任务驳回上一步骤
            var currentNode = await GetNodeByWorkflowIdAndNodeId(workTask.WorkflowId, currentWorkStep.NodeId);

            if (currentNode.NodeType == WorkNodeType.Begin)
                return ProveResult.Failed("开始步骤无法拒绝！");

            //更新当前处理节点为已处理
            currentWorkStep.Handle(WorkStepHandleType.Reject, comment, resourceIds);
            await workStepRepository.UpdateAsync(currentWorkStep);
            var steps = new List<WorkStep>();

            var nextNodes = await GetNextNodes(currentNode, workTask, currentWorkStep);
            //如果下一个节点是会签，则同组的步骤都要撤回
            if (nextNodes.Count == 1 && nextNodes[0].NodeType == WorkNodeType.Sign)
            {
                await UpdateStepsStatusWithUnworkflowed(currentWorkStep.NodeId, currentWorkStep.GroupId);
            }
            //从节点映射获取拒绝节点，如果指定了拒绝节点，则按照
            //var rejectNodes = await GetRejectNodes(currentNode, workTask, currentWorkStep);
            //if (currentNode.RejectNodes != null && currentNode.RejectNodes.Count > 0)
            //{
            //    var groupId = Guid.NewGuid().ToString();
            //    //如果指定了回滚的节点，则按指定节点回滚
            //    foreach (var rejectNode in currentNode.RejectNodes)
            //    {

            //        steps.AddRange(GetApproveSteps(currentWorkStep.NodeId, currentNode.Name, workTask, node, currentWorkStep.GroupId, groupId));
            //    }
            //}

            //获取拒绝的步骤（如果指定绝节节点则获取拒绝节点，否则退回上一步的节点，处理人员仍然 是上一步的人员）
            steps.AddRange(await GetRejectSteps(currentNode, workTask, currentWorkStep));
            if (steps.Count == 0)
                return ProveResult.Failed("找不到可以处理的下一个步骤！");
            await SendTasks(workTask, steps, formData);
            return ProveResult.Succeed(steps);
        }


        /// <summary>
        /// 撤回
        /// 只能撤回未读的记录
        /// </summary>
        /// <param name="workStepId"></param>
        /// <returns></returns>
        public async Task<ProveResult> Withdraw(Guid workStepId, string comment = null)
        {
            await Task.Delay(0);

            var currentWorkStep = await workStepRepository.GetAsync(workStepId);

            if (!currentWorkStep.IsHandled)
                return ProveResult.Failed("步骤未处理无法撤回！");

            var workTask = await workTaskRepository.GetAsync(currentWorkStep.WorkTaskId);

            var currentNode = await GetNodeByWorkflowIdAndNodeId(workTask.WorkflowId, currentWorkStep.NodeId);

            if (currentNode.NodeType == WorkNodeType.End)
                return ProveResult.Failed("已结束无法撤回！");

            var steps = new List<WorkStep>();

            var nextSteps = await workStepRepository.GetListAsync(ws => ws.PreStepGroupId == currentWorkStep.GroupId && ws.HandleType != WorkStepHandleType.Unworkflowed);
            //如果已读则不处理，否则执行撤回
            if (nextSteps.Count > 0 && nextSteps.Count(s => s.IsRead || s.IsHandled) == 0)
            {
                //设置后续节点为未处理
                foreach (var ns in nextSteps)
                {
                    ns.Handle(WorkStepHandleType.Unworkflowed, $"{comment},后续步骤自动设为未处理");
                    await workStepRepository.UpdateAsync(ns);
                }

                //设置当前节点为撤回状态
                //新插入当前步骤
                var withdrawStep = currentWorkStep.Copy();
                withdrawStep.Handle(WorkStepHandleType.Withdraw, comment);
                await workStepRepository.InsertAsync(withdrawStep);
                //新插入当前步骤
                var newStep = currentWorkStep.Copy();
                newStep.SetReaded();//对于撤回新插入的记录，它应该是已读的
                await workStepRepository.InsertAsync(newStep);
                steps.Add(newStep);
            }
            else
                return ProveResult.Failed("下一步骤已读或已处理，无法撤回！");
            if (steps.Count == 0)
                return ProveResult.Failed("找不到可以处理的下一个步骤！");
            return ProveResult.Succeed(steps);
        }

        /// <summary>
        /// 转发
        /// </summary>
        /// <param name="workStepId"></param>
        /// <param name="handleUsers">转发的目标成员</param>
        /// <param name="comment"></param>
        /// <returns></returns>
        public async Task<ProveResult> Forward(Guid workStepId, List<NodeUser> UserSelectors, string comment = null)
        {

            await Task.Delay(0);

            if (UserSelectors == null || UserSelectors.Count == 0)
                return ProveResult.Failed("未提供转办的用户或转办用户无效！"); ;

            var currentWorkStep = await workStepRepository.GetAsync(workStepId);
            var workTask = await workTaskRepository.GetAsync(currentWorkStep.WorkTaskId);
            var steps = new List<WorkStep>();


            //设置当前节点为转发状态
            currentWorkStep.Handle(WorkStepHandleType.Forward, comment);
            await workStepRepository.UpdateAsync(currentWorkStep);
            //插入新处理人的处理步骤
            //遍历用户 选择器获取实际用户 并转发处理
            foreach (var selector in UserSelectors)
            {
                var userSelector = userSelectorManager.GetUserSelector(selector.SelectorId);
                foreach (var section in selector.Selections)
                {
                    var _users = userSelector.GetUsers(new SelectorInput
                    {
                        SelectionId = section.Id,
                        Expression = selector.Parameter,
                        WorkTask = workTask
                    });

                    _users.ForEach(user =>
                    {
                        var newStep = currentWorkStep.Copy();
                        newStep.SetHandleUser(user);
                        workStepRepository.InsertAsync(newStep);
                        steps.Add(newStep);
                    });
                }

            }

            if (steps.Count == 0)
                return ProveResult.Failed("找不到可以处理的下一个步骤！");
            return ProveResult.Succeed(steps);
        }

        /// <summary>
        /// 获取正在处理的会签任务
        /// </summary>
        /// <param name="currentNodeId"></param>
        /// <param name="stepGroupId"></param>
        /// <returns></returns>
        private async Task<long> GetOnHandingSignStepsCount(Guid currentNodeId, string stepGroupId)
        {
            await Task.Delay(0);

            var steps = await workStepRepository.GetCountAsync(ws => ws.GroupId == stepGroupId && ws.IsHandled == false && ws.NodeId != currentNodeId);
            return steps;
        }

        /// <summary>
        /// 获取审批步骤
        /// </summary>
        /// <param name="fromNodeId"></param>
        /// <param name="fromNodeName"></param>
        /// <param name="workTask"></param>
        /// <param name="node"></param>
        /// <param name="preStepGroupId">上一步骤分组id</param>
        /// <param name="nextStepGroupId">下一步骤分组id</param>
        /// <returns></returns>
        private List<WorkStep> GetApproveSteps(Guid fromNodeId, string fromNodeName, WorkTask workTask, WorkflowNode node, string preStepGroupId, string nextStepGroupId)
        {
            List<WorkStep> steps = new List<WorkStep>();
            var nodeUsers = node.GetHandleUsers(workTask, userSelectorManager);

            foreach (var nodeUser in nodeUsers)
            {
                foreach (var user in nodeUser.Value)
                {
                    steps.Add(new WorkStep(Guid.NewGuid(), workTask.Id, fromNodeId, fromNodeName, node.Id, node.Name, new User
                    {
                        Id = user.Id,
                        Name = user.Name
                    }, nodeUser.Key == NodeUser.NodeHandleType.Handle ? WorkStepType.Handle : WorkStepType.ReadOnly, nextStepGroupId, preStepGroupId));
                }
            }
            return steps;
        }
        /// <summary>
        /// 根据选择器获取审批用户
        /// </summary>
        /// <param name="UserSelectors"></param>
        /// <param name="workTask"></param>
        /// <param name="userHandler"></param>
        private void GetUsersByUserSelectors(List<NodeUser> UserSelectors, WorkTask workTask, Action<User> userHandler)
        {
            foreach (var selector in UserSelectors)
            {
                var userSelector = userSelectorManager.GetUserSelector(selector.SelectorId);
                foreach (var selection in selector.Selections)
                {
                    var _users = userSelector.GetUsers(new SelectorInput
                    {
                        SelectionId = selection.Id,
                        Expression = selector.Parameter,
                        WorkTask = workTask
                    });

                    foreach (var user in _users)
                    {
                        userHandler?.Invoke(user);
                    }

                }
            }
        }

        /// <summary>
        /// 获取审批步骤
        /// </summary>
        /// <param name="fromNodeId"></param>
        /// <param name="fromNodeName"></param>
        /// <param name="workTask"></param>
        /// <param name="node"></param>
        /// <param name="preStepGroupId">上一步骤分组id</param>
        /// <param name="nextStepGroupId">下一步骤分组id</param>
        /// <returns></returns>
        private List<WorkStep> GetApproveSteps(Guid fromNodeId, string fromNodeName, WorkTask workTask, WorkflowNode node, string preStepGroupId, string nextStepGroupId, List<NodeUser> handlerUserSelectors = null, List<NodeUser> readUserSelectors = null)
        {
            List<WorkStep> steps = new List<WorkStep>();

            GetUsersByUserSelectors(handlerUserSelectors, null, user =>
            {
                steps.Add(new WorkStep(Guid.NewGuid(), workTask.Id, fromNodeId, fromNodeName, node.Id, node.Name, new User
                {
                    Id = user.Id,
                    Name = user.Name
                }, WorkStepType.Handle, nextStepGroupId, preStepGroupId));
            });

            GetUsersByUserSelectors(readUserSelectors, null, user =>
            {
                steps.Add(new WorkStep(Guid.NewGuid(), workTask.Id, fromNodeId, fromNodeName, node.Id, node.Name, new User
                {
                    Id = user.Id,
                    Name = user.Name
                }, WorkStepType.ReadOnly, nextStepGroupId, preStepGroupId));
            });

            return steps;
        }

        /// <summary>
        /// 分配任务到处理人员
        /// </summary>
        /// <param name="workTask"></param>
        /// <param name="workSteps"></param>
        /// <param name="formData"></param>
        /// <returns></returns>
        private async Task SendTasks(WorkTask workTask, List<WorkStep> workSteps, string formData = null)
        {
            await Task.Delay(0);
            foreach (var item in workSteps)
            {
                item.IsHandled = false;
                item.SetFormData(formData);
                await workStepRepository.InsertAsync(item);
                //TODO 发布开启任务事件
                //TODO 发布开启消息
                //TODO 考虑增加让步骤保存每次处理的表单信息
                eventManager.TriggerSendTask(workTask, item);
            }
        }

        /// <summary>
        /// 获取流程所有过程
        /// </summary>
        /// <param name="user"></param>
        /// <returns></returns>
        public async Task<List<WorkStep>> GetAllTaskStepsOfWorkTaskAsync(Guid workTaskId)
        {
            await Task.Delay(0);
            return (await workStepRepository.GetListAsync(ws => ws.WorkTaskId == workTaskId)).OrderByDescending(ws => ws.CreationTime).ToList();
        }


        /// <summary>
        /// 获取用户所有的流程任务
        /// </summary>
        /// <param name="user"></param>
        /// <returns></returns>
        public async Task<IEnumerable<WorkTask>> GetAllTasksOfUserAsync(User user)
        {
            await Task.Delay(0);
            var workTaskIds = (await workStepRepository.GetListAsync(ws => ws.HandleUser.Id == user.Id)).Select(ws => ws.WorkTaskId);

            var workTasks = (await workTaskRepository.GetListAsync(wt => workTaskIds.Contains(wt.Id))).OrderByDescending(ws => ws.CreationTime);

            return workTasks;
        }


        /// <summary>
        /// 获取用户已处理的流程任务
        /// </summary>
        /// <param name="user"></param>
        /// <returns></returns>
        public async Task<IEnumerable<WorkTask>> GetWorkflowedTasksOfUserAsync(User user)
        {
            var workTaskIds = (await workStepRepository.GetListAsync(ws => ws.HandleUser.Id == user.Id && ws.IsHandled)).Select(ws => ws.WorkTaskId);

            var workTasks = (await workTaskRepository.GetListAsync(wt => workTaskIds.Contains(wt.Id))).OrderByDescending(ws => ws.CreationTime);

            return workTasks;
        }

        /// <summary>
        /// 获取用户未处理的流程任务
        /// </summary>
        /// <param name="user"></param>
        /// <returns></returns>
        public async Task<IEnumerable<WorkTask>> GetUnworkflowedTasksOfUserAsync(User user)
        {
            var workTaskIds = (await workStepRepository.GetListAsync(ws => ws.HandleUser.Id == user.Id && !ws.IsHandled)).Select(ws => ws.WorkTaskId);

            var workTasks = (await workTaskRepository.GetListAsync(wt => workTaskIds.Contains(wt.Id))).OrderByDescending(ws => ws.CreationTime);
            return workTasks;
        }
        /// <summary>
        /// 用户发起的流程
        /// </summary>
        /// <param name="user"></param>
        /// <returns></returns>
        public async Task<IEnumerable<WorkTask>> GetTasksOfStartUserAsync(User user)
        {
            return await workTaskRepository.GetListAsync(wt => wt.ModifiedUserId == user.Id);
        }


        /// <summary>
        /// 获取选择器源数据,可提供前台选择
        /// </summary>
        /// <param name="selectorId"></param>
        /// <returns></returns>
        public async Task<List<Selection>> GetUserSelectionsOfUserSelector(string selectorId)
        {
            await Task.Delay(0);
            if (string.IsNullOrEmpty(selectorId)) return new List<Selection>();
            var userSelector = userSelectorManager.GetUserSelector(selectorId);
            return userSelector.GetSelections();
        }

        /// <summary>
        /// 删除流程
        /// 同时删除审批记录
        /// </summary>
        /// <param name="worktaskId"></param>
        /// <returns></returns>
        public async Task DeleteWorkTask(Guid worktaskId)
        {
            await workStepRepository.DeleteManyAsync(ws => ws.WorkTaskId == worktaskId);
            await workTaskRepository.DeleteAsync(worktaskId);
        }

        #endregion
    }
}
